package top.koqia.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.koqia.entity.Point;
import top.koqia.mapper.RandomCallMapper;
import top.koqia.service.IRandomCallService;
import top.koqia.vo.MapDto;

import java.util.*;
import java.util.concurrent.TimeUnit;

@SuppressWarnings("all")
@Service
@Transactional
public class IRandomCallServiceImpl implements IRandomCallService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RandomCallMapper randomCallMapper;

    @Override
    public MapDto randomCall(String type) {
        Set<String> set = new HashSet();
        Map<String, List> map = new HashMap<>();
        List<Point> call = new ArrayList<>();

//      查询数据
        List<Point> cache = inquiry();

//      排除JAVA|BI班
        Iterator<Point> point = cache.iterator();
        while (point.hasNext()) {
            if (!point.next().getClazz().startsWith(type)) {
                point.remove();
            }
        }
//      获取组名
        for (Point point1 : cache) {
            set.add(point1.getCord());
        }
//      创建分组
        for (String o : set) {
            map.put(o, new ArrayList<Point>());
        }
//      实行分组
        for (Point point1 : cache) {
            map.get(point1.getCord()).add(point1);
        }
//      根据组名随机点名
        for (String o : set) {
            List<Point> list = map.get(o);
            call.add(list.get(RandomUtil.randomInt(0, list.size())));
        }
//      排序
        call.sort(new Comparator<Point>() {
            @Override
            public int compare(Point o1, Point o2) {
//              初始化
                String substring1 = "1";
                String substring2 = "1";
//              根据组名长度截取数字
                if (o1.getCord().length() == 5) {
                    substring1 = o1.getCord().substring(2, 4);
                } else {
                    substring1 = o1.getCord().substring(2, 3);
                }
                if (o2.getCord().length() == 5) {
                    substring2 = o2.getCord().substring(2, 4);
                } else {
                    substring2 = o2.getCord().substring(2, 3);
                }
                return Integer.parseInt(substring1) - Integer.parseInt(substring2);
            }
        });
//      清空map表再次利用
        map.clear();
        map.put("data", call);
        return new MapDto(map);
    }

    @Override
    public MapDto randomCall(String num, String type) {
//      声明中间变量
        int temp = 1;
//      尝试强转
        try {
            temp = Integer.parseInt(num);
//      排除非法数据
            if (temp < 0) {
                temp = -temp;
            } else if (temp == 0) {
                temp = 1;
            }
        } catch (Exception exception) {
            System.out.println("数据不合法");
            temp = 1;
        }
        Set<Integer> set = new HashSet();
        Map map = new HashMap<>();
        List<Point> call = new ArrayList<>();
//      数据查询
        List<Point> cache = inquiry();
//      排除JAVA|BI班
        Iterator<Point> point = cache.iterator();
        while (point.hasNext()) {
            if (!point.next().getClazz().startsWith(type)) {
                point.remove();
            }
        }
//      保证范围不会越界
        temp = temp > cache.size() ? cache.size() : temp;
//      循环随机数且保证去重并保存下标
        for (int i = 0; i < temp || set.size() < temp; i++) {
            set.add(RandomUtil.randomInt(0, cache.size()));
        }
//      提取随机对象并保存
        for (Integer o : set) {
            call.add(cache.get(o));
        }
        map.put("data", call);
        map.put("res", true);
        return new MapDto(map);
    }


    //  查询代码封装
    private List<Point> inquiry() {
//      获取redis模板对象
        BoundValueOperations<String, String> allStaffInformation = redisTemplate.boundValueOps("allStaffInformation");
//      尝试查询缓存
        String data = allStaffInformation.get();
//      判断数据是否存在，若为空则传统查询并加入缓存
        if (data == null) {
//          查询
            List<Point> points = randomCallMapper.selectList(new QueryWrapper(new Point()));
//          Java对象转json字符串
            String jsonStr = JSONUtil.toJsonStr(points);
//          存入缓存
            allStaffInformation.set(jsonStr);
//          设置过期时间
            allStaffInformation.expire(10, TimeUnit.HOURS);
        }
//      将数据转换成Java对象
        List<Point> cache = JSONUtil.toList(data, Point.class);
        return cache;
    }
}
